package com.conner;

import java.awt.*;
import java.awt.event.*;
import java.io.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Scanner;
import javax.swing.*;
import javax.swing.event.*;

import com.conner.file_amend.FileCleaner;
import com.conner.file_types.*;

//TERMINAL:
    //TODO: Write terminal parser


//GUI:
    //TODO: Fix line numbers for logs.txt in checkbox window



public class Main extends JFrame implements ActionListener, WindowListener, ListSelectionListener, ComponentListener, KeyListener {

    Container cp = getContentPane();

    private Folder currentFolder;
    private Files currentFile;
    
    private FileCleaner fc = new FileCleaner();
    
    //Frame Elements
    private JLabel file_types,select_files,not_select,about_folder,about_files;

    private JComboBox dataTypes;
    private JList fileList_Selected, fileList_NotSelected;
    private JPanel errorList;
    private DefaultListModel list1 = new DefaultListModel();
    private DefaultListModel list2 = new DefaultListModel();

    private JMenuBar menu;
        private JMenu open_menu,about_menu;
        private JMenuItem openFolder,exit;
        private JCheckBoxMenuItem backup;

    private JButton removeFrom,addTo,finish,make_changes,rescan;

    private JScrollPane notSelectedFiles,selectedFiles,detailScroll,aboutScroll,errorScroll;

    private JTextArea fileDetails;

    private JInternalFrame aboutWindow;

    private JFileChooser fileChoose;

    private ArrayList<JCheckBox> errors = new ArrayList<JCheckBox>();


    //Starts main application
    public static void main(String[] args){
        new Main();
    }

    //Loads main application
    public Main(){
        //Content Pane Initializing
        cp.setLayout(null);
        cp.setBounds(0,0,0,0);
        cp.setBackground(Color.LIGHT_GRAY);

        init();

        addWindowListener(this);

        setJMenuBar(menu);
        pack();
        setTitle("File Fixer 2.0");
        setLocationRelativeTo(null);
        setResizable(false);
        setBounds(200,200,600,600);
        setVisible(true);
    }

    //Initializes swing components/interface
    public void init(){
        initMenuBar();
        initText();
        initButtons();
        initMisc();
    }

    //Trigger Actions from swing components
    public void actionPerformed(ActionEvent e){
        //Selects which folder to work with
        if(e.getSource() == openFolder){
            int returnVal = fileChoose.showOpenDialog(this);
            if(returnVal == JFileChooser.APPROVE_OPTION){
                currentFolder = new Folder(fileChoose.getSelectedFile().getPath());
                populateLists();
            }
        }

        //Adds selected file back into the selected files area
        if(e.getSource() == addTo){
            if(fileList_NotSelected.getSelectedIndex() > -1){
                String tempEntry = (String) list1.remove(fileList_NotSelected.getSelectedIndex());
                list2.addElement(tempEntry);
            }
        }

        //Removes selected file back into the unselected files area
        if(e.getSource() == removeFrom){
            if(fileList_Selected.getSelectedIndex() > -1){
                String tempEntry = (String) list2.remove(fileList_Selected.getSelectedIndex());
                list1.addElement(tempEntry);
            }
        }

        //Filters file types by selected type into selected files pane
        if(e.getSource() == dataTypes){
            for(Object str : list2.toArray()){
                list1.addElement(str);
                list2.removeElement(str);
            }
            for(Object str : list1.toArray()){
                String temp_str = (String)str;
                int pos = temp_str.lastIndexOf('.');
                if(temp_str.substring(pos+1).equalsIgnoreCase((String)dataTypes.getSelectedItem())){
                    list2.addElement(str);
                    list1.removeElement(str);
                }
            }
        }
        if(e.getSource() == rescan) scanFiles();
        if(e.getSource() == exit) System.exit(0);
    }

    public void scanFiles(){
        //Collects files in the selected area to be cleaned
        Folder toBeCleaned = new Folder();
        for(Object e:list2.toArray()){
            for(Files f:currentFolder.getFolder()){
                if(f.getFileName().equals((String) e)){
                    toBeCleaned.addFile(f);
                }
            }
        }
        
        //Scans for errors in the selected file area
        HashMap<String, HashMap<Integer, String>> collectedErrors = new HashMap<String, HashMap<Integer, String>>();

        for(Files f: toBeCleaned.getFolder()){
            HashMap<Integer, String> temp = fc.startCleanup(f);
            if(temp.size() > 0){
                collectedErrors.put(f.getFileName(), temp);
            }
        }
        
        errors.clear();
        errorList.removeAll();
        for(String key: collectedErrors.keySet()){
            for(String newError:collectedErrors.get(key).values()){
                errors.add(new JCheckBox(key+": "+ newError));
            }
        }
        if(errors != null)
            for(JCheckBox e:errors){
                errorList.add(e);
            }
        errorScroll.updateUI();
    }

    //Updates labels and lists of files
    public void populateLists(){
        //Refresh JLabels
        about_folder.setText("Current Folder: " + (currentFolder != null?currentFolder.directory:""));
        about_files.setText("Contains: " + (currentFolder != null?currentFolder.totalFiles():0) + " file(s)");

        //Fills Lists with files
        list1.clear();
        list2.clear();
        for(File e : currentFolder.getFiles()){
            list1.addElement(e.getName());
        }

        //Collects/updates file types in selected folder
        dataTypes.removeAllItems();
        HashMap<String,Integer> temp = new HashMap<String,Integer>();
        for(Files e : currentFolder.getFolder()){
            temp.put(e.getFileType(),0);
        }
        for(String e : temp.keySet()){
            dataTypes.addItem(e);
        }
    }

    //Init menu graphics
    public void initMenuBar(){
        menu = new JMenuBar();
        open_menu = new JMenu("File");
        about_menu = new JMenu("About");
        menu.add(open_menu);
        menu.add(about_menu);

        openFolder = new JMenuItem("Select Folder...");
        exit = new JMenuItem("Exit");
        backup = new JCheckBoxMenuItem("Backup on Apply");
        backup.setSelected(true);

        open_menu.add(openFolder);
        open_menu.addSeparator();
        open_menu.add(backup);
        open_menu.addSeparator();
        open_menu.add(exit);

        openFolder.addActionListener(this);
        exit.addActionListener(this);
        about_menu.addActionListener(this);
    }

    //Init Jlabels
    public void initText(){
        file_types = new JLabel("Data Type to Filter: ");
        file_types.setBounds(5,5,200,20);
        select_files = new JLabel("Unselected Files:");
        select_files.setBounds(5,29,100,30);
        not_select = new JLabel("Selected Files:");
        not_select.setBounds(190,29,100,30);
        about_folder = new JLabel("Current Folder: "+ (currentFolder != null? currentFolder.directory : ""));
        about_files = new JLabel("Contains: " + (currentFolder != null? currentFolder.totalFiles() : 0) + " files");
        about_folder.setBounds(269,4,400,30);
        about_files.setBounds(300,19,200,30);

        cp.add(file_types);
        cp.add(select_files);
        cp.add(not_select);
        cp.add(about_folder);
        cp.add(about_files);
    }

    //Init JButtons
    public void initButtons(){
        removeFrom = new JButton("<");
        removeFrom.setBounds(150,125,44,30);
        addTo = new JButton(">");
        addTo.setBounds(150,165,44,30);
        make_changes = new JButton("Apply Selected Changes");
        make_changes.setBounds(200,515,200,30);
        rescan = new JButton("Rescan Files");
        rescan.setBounds(5,515,190,30);
        finish = new JButton("Finish and Backup");
        finish.setBounds(405,515,185,30);
        
        removeFrom.addActionListener(this);
        addTo.addActionListener(this);
        make_changes.addActionListener(this);
        rescan.addActionListener(this);
        finish.addActionListener(this);
        
        cp.add(removeFrom);
        cp.add(addTo);
        cp.add(make_changes);
        cp.add(rescan);
        cp.add(finish);
    }

    //Init's any other applied Swing Graphics
    public void initMisc(){
        fileChoose = new JFileChooser();
        fileChoose.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
        fileChoose.setBounds(10,10,300,300);

        dataTypes = new JComboBox();
        dataTypes.setBounds(115,6,90,20);

        fileList_Selected = new JList(list2);
        fileList_NotSelected = new JList(list1);
        notSelectedFiles = new JScrollPane(fileList_NotSelected);
        selectedFiles = new JScrollPane(fileList_Selected);
        selectedFiles.setBounds(190,50,150,240);
        notSelectedFiles.setBounds(5,50,150,240);
        errorList = new JPanel();
        errorList.setLayout(new BoxLayout(errorList, BoxLayout.Y_AXIS));

        errorScroll = new JScrollPane(errorList);
        errorScroll.setBounds(5,310,585,200);
        fileDetails = new JTextArea();
        detailScroll = new JScrollPane(fileDetails);
        detailScroll.setBounds(345,50,245,240);

        fileList_NotSelected.addListSelectionListener(this);
        fileList_Selected.addListSelectionListener(this);
        dataTypes.addActionListener(this);
        fileDetails.addKeyListener(this);
        cp.add(dataTypes);
        cp.add(notSelectedFiles);
        cp.add(selectedFiles);
        cp.add(detailScroll);
        cp.add(errorScroll);
    }

    public void keyPressed(KeyEvent arg0) {

    }

    ///Saves any editted information in details pane to the selected file ('Files' Class type file)
    public void keyReleased(KeyEvent arg0) {
        if(arg0.getSource() == fileDetails){
            currentFile.setInformation(fileDetails.getText());
        }
    }
    public void keyTyped(KeyEvent arg0) {

    }
    public void componentHidden(ComponentEvent arg0) {

    }
    public void componentMoved(ComponentEvent arg0) {

    }
    public void componentResized(ComponentEvent arg0) {

    }
    public void componentShown(ComponentEvent arg0) {

    }

    //Updates Detail pane on far right of what the file contains (Text-wise)
    public void valueChanged(ListSelectionEvent e) {
        if(e.getSource() == fileList_NotSelected && currentFolder != null && fileList_NotSelected.getSelectedIndex() > -1){
            if(currentFolder.getFiles().length > 0){
                for(int i = 0; i < currentFolder.getFiles().length; i++){
                    if(currentFolder.getFileName(i).equals((String)list1.getElementAt(fileList_NotSelected.getSelectedIndex()))){
                        fileDetails.setText(currentFolder.getFileDetails(i));
                        currentFile = currentFolder.getFile2(i);
                        break;
                    }
                }
            }
        }
        if(e.getSource() == fileList_Selected && currentFolder != null && fileList_Selected.getSelectedIndex() > -1){
            if(currentFolder.getFiles().length > 0){
                for(int i = 0; i < currentFolder.getFiles().length; i++){
                    if(currentFolder.getFileName(i).equals((String)list2.getElementAt(fileList_Selected.getSelectedIndex()))){
                        fileDetails.setText(currentFolder.getFileDetails(i));
                        currentFile = currentFolder.getFile2(i);
                        break;
                    }
                }
            }
        }
    }
    public void windowActivated(WindowEvent arg0) {

    }
    public void windowClosed(WindowEvent arg0) {

    }
    public void windowClosing(WindowEvent arg0) {
        System.exit(0);
    }
    public void windowDeactivated(WindowEvent arg0) {

    }
    public void windowDeiconified(WindowEvent arg0) {

    }
    public void windowIconified(WindowEvent arg0) {

    }
    public void windowOpened(WindowEvent arg0) {
    }
}
